package com.act.moudles.act.service.impl;

import com.act.constant.TaskAnoTypeEnums;
import com.act.moudles.act.compents.ActCompent;
import com.act.moudles.act.pojo.TaskRunPojo;
import com.act.moudles.act.pojo.TaskSearchPojo;
import com.act.moudles.act.service.TaskListService;
import com.act.moudles.act.vo.TaskLog;
import com.act.moudles.act.vo.TaskVo;
import com.act.moudles.baseAct.dao.OnlineDeployDao;
import com.act.moudles.baseAct.dao.TaskAnoDao;
import com.act.moudles.baseAct.dao.TaskAnoVarsDao;
import com.act.moudles.baseAct.entity.OnlineDeploy;
import com.act.moudles.baseAct.entity.TaskAno;
import com.act.moudles.baseAct.entity.TaskAnoVars;
import com.act.moudles.user.entity.User;
import com.act.utils.PageSearch;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: mengxiangzhong
 * @date: 2023/5/16 16:00
 * @TODO:
 **/

@Service
public class TaskListServiceImpl implements TaskListService {

    /**
     * 运行时服务，可以处理所有正在运行状态的流程实例，任务等
     * 主要用来开启流程实例，一个流程实例对应多个任务，也就是多个流程节点
     */
    @Resource
    private RuntimeService runtimeService;

    /**
     * 仓储服务，用于管理流程仓库，例如：部署，删除，读取流程资源
     * 可以用来部署我们的流程图，还可以创建我们的流程部署查询对象，用于查询刚刚部署的流程列表，便于我们管理流程
     */
    @Resource
    private RepositoryService repositoryService;

    /**
     * 任务服务，用于管理，查询任务，例如：签收，办理，指派等
     * 是用来可以用来领取，完成，查询任务列表功能的
     */
    @Resource
    private org.activiti.engine.TaskService taskService;

    @Resource
    private HistoryService historyService;


    @Resource
    private OnlineDeployDao onlineDeployDao;

    @Resource
    private TaskAnoDao taskAnoDao;

    @Resource
    private TaskAnoVarsDao taskAnoVarsDao;

    @Resource
    private ActCompent actCompent;



    @Override
    public List<Map<String,Object>> findStartParams(String userFlowKey, User user) throws Exception{
        //1.验证用户信息
        String flowKey = null;
        try {
            flowKey = actCompent.checkAndToFlowKey(userFlowKey,user.getTenantId());
        }catch (Exception e){
            e.printStackTrace();
            throw  new RuntimeException(e.getMessage());
        }

        //2.查询第一个方法
        TaskAno minTask = taskAnoDao.selectminByUserFlowKey(userFlowKey, TaskAnoTypeEnums.USER_TASK.getTaskType());

        //3.查询方法变量
        List<Map<String,Object>>  list = new ArrayList<>();
        for(TaskAnoVars vars : taskAnoVarsDao.selectByAnoId(minTask.getId())){
            Map<String,Object> map = new HashMap<>();
            map.put("key",vars.getVarKey());
            map.put("name",vars.getVarName());
            map.put("value","");
            list.add(map);
         }
        return list;
    }


    @Override
    public IPage<TaskVo>  findAssTodoTask(PageSearch page,  TaskSearchPojo pojo)throws Exception {
        //1.构建task查询query
        TaskQuery query = taskService.createTaskQuery();
        if(StringUtils.isNotEmpty(pojo.getDeployName())){
            LambdaQueryWrapper<OnlineDeploy> depQuery = new LambdaQueryWrapper<>();
            depQuery.like(OnlineDeploy::getDepeloyName,pojo.getDeployName());
            List<OnlineDeploy>  list = onlineDeployDao.selectList(depQuery);
            query.processDefinitionKeyIn(list.stream().map(OnlineDeploy::getProcdefKey).collect(Collectors.toList()));
        }

        if(StringUtils.isNotEmpty(pojo.getAssginee())){
            query.taskAssignee(pojo.getAssginee());
        }
        if(StringUtils.isNotEmpty(pojo.getTenantId())){
            query.taskTenantId(pojo.getTenantId());
        }
        if(StringUtils.isNotEmpty(pojo.getUserFlowKey())){
            OnlineDeploy dep = onlineDeployDao.selectByUserFlowKey(pojo.getUserFlowKey());
            if(dep == null){
                throw  new RuntimeException("流程不存在");
            }
            query.processDefinitionKey(dep.getProcdefKey());
        }

        if(StringUtils.isNotEmpty(pojo.getProcId())){
            query.processInstanceId(pojo.getProcId());
        }
        query.orderByTaskCreateTime().desc();
        //2.分页查询
        List<Task> taskList = query.listPage(page.getPageNum() * page.getPageSize() - page.getPageSize(),page.getPageNum() * page.getPageSize());
        IPage<TaskVo> voPage = new Page<TaskVo>(page.getPageNum(),page.getPageSize(),query.count());
        voPage.setRecords(voPage.getTotal() == 0?new ArrayList<>():actCompent.buildTaskVo(taskList));
        return voPage;
    }

    @Override
    public IPage<TaskVo> findAssStartTask(PageSearch page, TaskSearchPojo pojo) throws Exception {
        //1.构建查询条件
        HistoricProcessInstanceQuery query =historyService.createHistoricProcessInstanceQuery();
        if(StringUtils.isNotEmpty(pojo.getDeployName())){
            LambdaQueryWrapper<OnlineDeploy> depQuery = new LambdaQueryWrapper<>();
            depQuery.like(OnlineDeploy::getDepeloyName,pojo.getDeployName());
            List<OnlineDeploy>  list = onlineDeployDao.selectList(depQuery);
            query.processDefinitionKeyIn(list.stream().map(OnlineDeploy::getProcdefKey).collect(Collectors.toList()));
        }

        if(StringUtils.isNotEmpty(pojo.getTenantId())){
            query.processInstanceTenantId(pojo.getTenantId());
        }
        if(StringUtils.isNotEmpty(pojo.getUserFlowKey())){
            OnlineDeploy dep = onlineDeployDao.selectByUserFlowKey(pojo.getUserFlowKey());
            if(dep == null){
                throw  new RuntimeException("流程不存在");
            }
            query.processDefinitionKey(dep.getProcdefKey());
        }

        if(StringUtils.isNotEmpty(pojo.getProcId())){
            query.processInstanceId(pojo.getProcId());
        }
        if(StringUtils.isNotEmpty(pojo.getAssginee())){
            query.startedBy(pojo.getAssginee());
        }
        query.orderByProcessInstanceEndTime().desc();

        //2.分页查询
        List<HistoricProcessInstance> taskList = query.listPage(page.getPageNum() * page.getPageSize() - page.getPageSize(),page.getPageNum() * page.getPageSize());
        IPage<TaskVo> voPage = new Page<>(page.getPageNum(),page.getPageSize(),query.count());
        voPage.setRecords(voPage.getTotal() == 0?new ArrayList<>():actCompent.buildProcHistVo(taskList,pojo));
        return voPage;
    }

    @Override
    public IPage<TaskVo> findAssHasTask(PageSearch page, TaskSearchPojo pojo) throws Exception {

        //。1构建查询条件
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
        if(StringUtils.isNotEmpty(pojo.getDeployName())){
            LambdaQueryWrapper<OnlineDeploy> depQuery = new LambdaQueryWrapper<>();
            depQuery.like(OnlineDeploy::getDepeloyName,pojo.getDeployName());
            List<OnlineDeploy>  list = onlineDeployDao.selectList(depQuery);
            query.processDefinitionKeyIn(list.stream().map(OnlineDeploy::getProcdefKey).collect(Collectors.toList()));
        }

        if(StringUtils.isNotEmpty(pojo.getTenantId())){
            query.taskTenantId(pojo.getTenantId());
        }
        if(StringUtils.isNotEmpty(pojo.getUserFlowKey())){
            OnlineDeploy dep = onlineDeployDao.selectByUserFlowKey(pojo.getUserFlowKey());
            if(dep == null){
                throw  new RuntimeException("流程不存在");
            }
            query.processDefinitionKey(dep.getProcdefKey());
        }

        if(StringUtils.isNotEmpty(pojo.getProcId())){
            query.processInstanceId(pojo.getProcId());
        }
        if(StringUtils.isNotEmpty(pojo.getAssginee())){
            query.taskAssignee(pojo.getAssginee());
        }
        query. finished();
        query.orderByHistoricTaskInstanceEndTime().desc();

        //2.分页查询
        List<HistoricTaskInstance> taskList = query.listPage(page.getPageNum() * page.getPageSize() - page.getPageSize(),page.getPageNum() * page.getPageSize());
        IPage<TaskVo> voPage = new Page<TaskVo>(page.getPageNum(),page.getPageSize(),query.count());
        voPage.setRecords(voPage.getTotal() == 0?new ArrayList<>():actCompent.buildTaskHistVo(taskList));
        return voPage;
    }

    @Override
    public IPage<TaskVo> findAssDoTask(PageSearch page, TaskSearchPojo pojo) throws Exception {
        //构建查询条件
        HistoricProcessInstanceQuery query =historyService.createHistoricProcessInstanceQuery()
                                            .processInstanceTenantId(pojo.getTenantId())
                                            .involvedUser(pojo.getAssginee());
        if(StringUtils.isNotEmpty(pojo.getDeployName())){
            LambdaQueryWrapper<OnlineDeploy> depQuery = new LambdaQueryWrapper<>();
            depQuery.like(OnlineDeploy::getDepeloyName,pojo.getDeployName());
            List<OnlineDeploy>  list = onlineDeployDao.selectList(depQuery);
            query.processDefinitionKeyIn(list.stream().map(OnlineDeploy::getProcdefKey).collect(Collectors.toList()));
        }
        //2.分页查询
        List<HistoricProcessInstance> taskList = query.listPage(page.getPageNum() * page.getPageSize() - page.getPageSize(),page.getPageNum() * page.getPageSize());
        IPage<TaskVo> voPage = new Page<>(page.getPageNum(),page.getPageSize(),query.count());
        voPage.setRecords(voPage.getTotal() == 0?new ArrayList<>():actCompent.buildProcHistVo(taskList,pojo));
        return voPage;
    }

    @Override
    public List<TaskLog> listLog(String procId, String userFlowkey, User user) throws Exception {
        //验证
        try {
            actCompent.checkAndToFlowKey(userFlowkey,user.getTenantId());
        }catch (Exception e){
            e.printStackTrace();
            throw  new RuntimeException(e.getMessage());
        }
        //查询
        List<HistoricTaskInstance> list = historyService
                .createHistoricTaskInstanceQuery()
                .processInstanceId(procId)
                .list();

        //构建Vo
        List<TaskLog> taskLogList = new ArrayList<>();
        for(HistoricTaskInstance  his : list){
            TaskLog taskLog = TaskLog.builder()
                    .procId(his.getProcessInstanceId())
                    .taskName(his.getName())
                    .assginee(his.getAssignee())
                    .startTime(his.getStartTime())
                    .endTime(his.getEndTime())
                    //TODO: 构建备注
                    .build();
            taskLogList.add(taskLog);
        }
        return taskLogList;
    }











}
